package main

import (
	"fmt"
	"unsafe"
)

func main() {
	//common.UnsafeTest2()
	test1()
	//test2()
	test3()
}

type name struct {
	a int
	b int
}

func test1() {
	var i int = 1
	fmt.Printf("1： value: %d, address: %p  ,convert:%d\n", i, &i, &i)
	x := &i
	*x += 1
	fmt.Printf("2： obj:%d    value: %d, address: %p\n", *x, x, &x)
	p := unsafe.Pointer(&i)
	fmt.Printf("3:  value： %d, address： %p\n", p, &p)

	fmt.Printf("1： value: %d, address: %p  ,convert:%d\n", i, &i, &i)
}

func test2() {
	t := name{}
	t.a = 100
	t.b = 200
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.a, &t.a, &t.a)
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.b, &t.b, &t.b)

	p := unsafe.Pointer(&t)
	pb := (*byte)(p)
	*pb = 10
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.a, &t.a, &t.a)
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.b, &t.b, &t.b)

	p = unsafe.Pointer(&t)
	up0 := uintptr(p)
	up := up0 + unsafe.Offsetof(t.b)
	up1 := unsafe.Pointer(up)

	pb = (*byte)(up1)
	*pb = 20
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.a, &t.a, &t.a)
	fmt.Printf("Self： value: %d, address: %p  ,convert:%d\n", t.b, &t.b, &t.b)
}

func test3() {
	var i = 1
	p := unsafe.Pointer(&i)
	t3(p)
	fmt.Printf("First:  value:%d,addr:%p\n", i, &i)

	x := &i
	t31(x)
	fmt.Printf("Second: value:%d,addr:%p\n", i, &i)

	p1 := unsafe.Pointer(&i)
	t32(p1)
	fmt.Printf("First:  value:%d,addr:%p\n", i, &i)

	y := &i
	t33(y)
	fmt.Printf("Second: value:%d,addr:%p\n", i, &i)

}

func t3(p unsafe.Pointer) {
	var x = 300
	pb := (*int)(p)
	*pb = x
}

func t31(i *int) {
	*i = 100
}

func t32(p unsafe.Pointer) {
	var i = 200
	x := unsafe.Pointer(&i)
	pb := (*int)(p)
	px := (*int)(x)
	*pb = *px
}

func t33(i *int) {
	var x = 400
	i = &x
}
